; void generarPlasma(Color rgb);
	; x = colores[(g_ver0 + 5 * columna) % 512] + 
	;     colores[(g_ver1 + 3 * columna) % 512] + 
	;     colores[(g_hor0 + 3 * fila   ) % 512] + 
	;     colores[(g_hor1 +     fila   ) % 512];

; constantes globales
	%include "constantes.mac"

; parametros
	%define rgb [ebp + 8]

	%define bytes_reservados 20

; variables locales
	%define p_fila 				[ebp - 16]
	%define p_columna 			[ebp - 20]
	%define p_pantalla		 	[ebp - 24]

	%define var_x		 		[ebp - 28]
	%define ancho_fondo_bytes 	[ebp - 32]

	extern screen_pixeles	;extern Uint8 *screen_pixeles
	extern colores			;extern int colores[]

	extern g_ver0			;extern Uint16 g_ver0
	extern g_ver1			;extern Uint16 g_ver1
	extern g_hor0			;extern Uint16 g_hor0
	extern g_hor1			;extern Uint16 g_hor1

global generarPlasma

section .text

generarPlasma:
	push ebp		; creo el marco de la pila
	mov ebp, esp	; creo el marco de la pila
	
	push ebx		; salvo registros convencion C
	push edi		; salvo registros convencion C
	push esi		; salvo registros convencion C

	sub esp, bytes_reservados	; reservo memoria en la pila

calculo_ancho_fondo_bytes:
	mov eax, ancho_pantalla
	mov ebx, bytes_por_pixel
	mul ebx
	mov dword ancho_fondo_bytes, eax

inicializar_variables:
	mov dword p_fila, 0		; p_fila = 0

	mov eax, [screen_pixeles]		; p_pantalla = screen_pixels
	mov p_pantalla, eax				; p_pantalla = screen_pixels

	xor esi, esi					; esi = contador de fila = 0

para_cada_fila:

	cmp esi, alto_pantalla		; esi = alto_pantalla ? termino
	je fin						; esi = alto_pantalla ? termino
	mov eax, p_fila
	mov p_columna, eax			; p_columna = p_fila

	xor edi, edi				; edi = contador de columna = 0

para_cada_columna:

	cmp edi, ancho_pantalla		; edi = ancho_pantalla ? cambio de fila
	je siguiente_fila			; edi = ancho_pantalla ? cambio de fila

es_color_off:

	mov eax, p_pantalla			; el pixel es color off?
	mov eax, dword [eax]		; el pixel es color off?
	and eax, 0x00FFFFFF			; el pixel es color off?

	mov edx, rgb				; el pixel es color off?
 	and edx, 0x00FFFFFF			; el pixel es color off?
	cmp eax, edx				; el pixel es color off?

	jne muevo_punteros			; el pixel es color off?

calculo_color:

	mov dword var_x, 0			; inicializo var_x	

	;colores[(g_ver0 + 5 * columna) % 512]
	mov eax, 5
	mul edi
	mov ebx, eax
	add ebx, dword [g_ver0]
	and ebx, 0x000001FF
	mov eax, [colores + ebx * 4]
	add dword var_x, eax

	;colores[(g_ver1 + 3 * columna) % 512]
	mov eax, 3
	mul edi
	mov ebx, eax
	add ebx, dword [g_ver1]
	and ebx, 0x000001FF
	mov eax, [colores + ebx * 4]
	add dword var_x, eax

	;colores[(g_hor0 + 3 * fila) % 512]
	mov eax, 3
	mul esi
	mov ebx, eax
	add ebx, dword [g_hor0]
	and ebx, 0x000001FF
	mov eax, [colores + ebx * 4]
	add dword var_x, eax

	;colores[(g_hor1 + fila) % 512]
	mov ebx, dword [g_hor1]
	add ebx, esi
	and ebx, 0x000001FF
	mov eax, [colores + ebx * 4]
	add dword var_x, eax

comparo_var_x:

	shr dword var_x, 4			; x >> 4
	mov dl, 128
	add dl, byte var_x

	mov ebx, p_pantalla			; ebx = p_pantalla

	cmp edx, 64
	jl asigno_color_menor_64

	cmp edx, 128
	jl asigno_color_menor_128

	cmp edx, 192
	jl asigno_color_menor_192

	cmp edx, 256
	jl asigno_color_menor_256

	jmp asigno_color_mayor_igual_256

asigno_color_menor_64:

	shl dl, 2
	mov [ebx+1], dl			; le cambio el color al BYTE de la pantalla
	inc dl
	mov al, 255
	sub al, dl
	mov [ebx+0], al			; le cambio el color al BYTE de la pantalla
	mov [ebx+2], byte 0		; le cambio el color al BYTE de la pantalla

	jmp muevo_punteros

asigno_color_menor_128:

	shl dl, 2
	inc dl
	mov [ebx+0], dl			; le cambio el color al BYTE de la pantalla
	mov [ebx+1], byte 255	; le cambio el color al BYTE de la pantalla
	mov [ebx+2], byte 0		; le cambio el color al BYTE de la pantalla

	jmp muevo_punteros

asigno_color_menor_192:

	shl dl, 2
	inc dl
	mov al, 255
	sub al, dl
	mov [ebx+0], al			; le cambio el color al BYTE de la pantalla
	mov [ebx+1], al			; le cambio el color al BYTE de la pantalla
	mov [ebx+2], byte 0		; le cambio el color al BYTE de la pantalla

	jmp muevo_punteros

asigno_color_menor_256:

	shl dl, 2
	inc dl
	mov [ebx+0], dl			; le cambio el color al BYTE de la pantalla
	mov [ebx+1], byte 0		; le cambio el color al BYTE de la pantalla
	mov [ebx+2], byte 0		; le cambio el color al BYTE de la pantalla

	jmp muevo_punteros

asigno_color_mayor_igual_256:

	mov [ebx+0], byte 0		; le cambio el color al BYTE de la pantalla
	mov [ebx+1], byte 0		; le cambio el color al BYTE de la pantalla
	mov [ebx+2], byte 0		; le cambio el color al BYTE de la pantalla

muevo_punteros:

	mov eax, p_pantalla			; avanzo puntero pantalla un pixel
	add eax, bytes_por_pixel	; avanzo puntero pantalla un pixel
	mov p_pantalla, eax			; avanzo puntero pantalla un pixel

	mov eax, p_columna			; avanzo puntero columna un pixel
	add eax, bytes_por_pixel	; avanzo puntero columna un pixel
	mov p_columna, eax			; avanzo puntero columna un pixel

siguiente_columna:

	inc edi
	jmp para_cada_columna

siguiente_fila:

	inc esi
	mov eax, ancho_fondo_bytes
	add p_fila, eax

	jmp para_cada_fila

fin:
	add dword [g_ver0], 9
	add dword [g_hor0], 8

	add esp, bytes_reservados	; desarmo el stack frame

	pop esi						; desarmo el stack frame
	pop edi						; desarmo el stack frame
	pop ebx						; desarmo el stack frame
	pop ebp						; desarmo el stack frame

	ret
